package net.yeah.mickey_zhouyou.util.fcs.elem;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.RandomAccess;
import java.util.Set;
import java.util.TreeSet;

import javax.script.ScriptContext;

import net.yeah.mickey_zhouyou.util.fcs.ReaderOverException;
import net.yeah.mickey_zhouyou.util.fcs.ReaderWrapper;
import net.yeah.mickey_zhouyou.util.fcs.SyntaxException;
import net.yeah.mickey_zhouyou.util.fcs.serialize.IConvertor;

public class IdxSelector extends Selector {
	private int[] idxs;

	public static IdxSelector create(ReaderWrapper reader) throws IOException {
		char b;
		try {
			b = reader.readNotBlank();
		} catch (ReaderOverException e) {
			throw new SyntaxException("索引选择器必须以一个[开头", reader.getCurrentRow(),
					reader.getCurrentColumn());
		}
		if (b == '[') {
			String s;
			try {
				s = reader.readUntil(']');
			} catch (ReaderOverException e1) {
				s = null;
			}
			if (s != null && s.length() > 0 && s.charAt(s.length() - 1) == ']') {
				s = s.substring(0, s.length() - 1);
				String[] ss = s.split(",");
				Set<Integer> res = new TreeSet<Integer>();
				for (String str : ss) {
					String[] ns = str.split("-");
					if (ns != null) {
						try {
							if (ns.length == 1)
								res.add(Integer.valueOf(ns[0]));
							else if (ns.length == 2) {
								Integer from = Integer.valueOf(ns[0]);
								Integer to = Integer.valueOf(ns[1]);
								for (int i = from; i <= to; ++i)
									res.add(i);
							} else
								throw new SyntaxException("索引选择器连字符不能连续使用多个",
										reader.getCurrentRow(),
										reader.getCurrentColumn());
						} catch (NumberFormatException e) {
							throw new SyntaxException("索引选择器内存在无法转为整数的东西",
									reader.getCurrentRow(),
									reader.getCurrentColumn());
						}
					}
				}
				Integer[] is = new Integer[res.size()];
				is = res.toArray(is);
				IdxSelector idxSelector = new IdxSelector();
				idxSelector.idxs = new int[is.length];
				for (int i = 0; i < is.length; ++i)
					idxSelector.idxs[i] = is[i];
				return idxSelector;
			}
			throw new SyntaxException("索引选择器必须以一个]结束", reader.getCurrentRow(),
					reader.getCurrentColumn());
		}
		throw new SyntaxException("索引选择器必须以一个[开头", reader.getCurrentRow(),
				reader.getCurrentColumn());
	}

	@Override
	public Object select(Object obj, IConvertor objConvertor,
			ScriptContext context) {
		if (obj == null)
			return null;
		if (obj.getClass().isArray()) {
			List<Object> res;
			if (idxs == null || idxs.length == 0) {
				int len = Array.getLength(obj);
				res = new ArrayList<Object>(len);
				for (int i = 0; i < len; ++i)
					res.add(Array.get(obj, i));
			} else {
				res = new ArrayList<Object>(idxs.length);
				for (int idx : idxs)
					res.add(Array.get(obj, idx));
			}
			return res;
		} else if (obj instanceof List) {
			List<?> list = (List<?>) obj;
			if (idxs == null || idxs.length == 0)
				return new ArrayList<Object>(list);
			else {
				List<Object> res = new ArrayList<Object>(idxs.length);
				if (obj instanceof RandomAccess) {
					for (int idx : idxs)
						res.add(list.get(idx));
				} else {
					// 非随机访问有待优化
					for (int idx : idxs)
						res.add(list.get(idx));
				}
				return res;
			}
		}
		throw new RuntimeException("只有数组和列表才可以使用索引选择器");
	}
}
